﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Alma.Core
{
    public static class SearchTokenizer
    {
        private enum TokenState
        {
            Void,
            Word,
            Operator,
            InQuotes
        }

        public static List<string> Tokenise(IEnumerable<char> input)
        {
            var tokens = new List<string>();
            var buffer = "";
            var state = TokenState.Void;
            var operators = new HashSet<string>() { "|", "+", ")", "(", "-", ":", "@" };

            foreach (var c in input)
            {
                if (state == TokenState.InQuotes)
                {
                    if (c == '"')
                        state = TokenState.Word;
                    else
                        buffer += c;
                }
                else if (char.IsLetterOrDigit(c) && state != TokenState.Void && state != TokenState.Word)
                {
                    tokens.Add(buffer);
                    buffer = "" + c;
                    state = TokenState.Word;
                }
                else if (char.IsLetterOrDigit(c) && (state == TokenState.Word || state == TokenState.Void))
                {
                    buffer += c;
                    state = TokenState.Word;
                }
                else if (!char.IsLetterOrDigit(c) && state != TokenState.InQuotes)
                {
                    if ((state == TokenState.Word && c != '"') || operators.Contains(buffer))
                    {
                        tokens.Add(buffer);
                        buffer = "";
                        state = TokenState.Void;
                    }

                    if ((c == '\t' || c == ' '))
                    {
                        if (state != TokenState.Void)
                        {

                            tokens.Add(buffer);
                            buffer = "";
                            state = TokenState.Void;
                        }
                    }
                    else if (c == '"')
                    {
                        state = TokenState.InQuotes;
                    }
                    else
                    {
                        buffer += c;
                        state = TokenState.Operator;
                    }
                }

            }
            if (state != TokenState.Void)
            {
                tokens.Add(buffer);
            }
            return tokens;
        }
    }
}